/* eslint-disable no-prototype-builtins */
/**
 * 判断两数组字符串是否相同（用于按钮权限验证），数组字符串中存在相同时会自动去重（按钮权限标识不会重复）
 * @param {Array} updatedArr 新数据
 * @param {Array<string>} oldArr 源数据
 * @returns {boolean} 两数组相同返回 `true`，反之则反
 */
export function judgementSameArr(
  updatedArr: unknown[] | string[],
  oldArr: string[]
): boolean {
  const updated = removeDuplicate(updatedArr)
  const olds = removeDuplicate(oldArr)
  let count = 0
  const leng = updated.length
  for (const index in olds) {
    for (const innerIndex in updated) {
      if (olds[index] === updated[innerIndex]) {
        count++
      }
    }
  }
  return count === leng ? true : false
}

/**
 * 判断两个对象是否相同
 * @param {*} a 要比较的对象一
 * @param {*} b 要比较的对象二
 * @returns {boolean} 相同返回 true，反之则反
 */
export function isObjectValueEqual<T extends { [key: string]: any }>(a: T, b: T): boolean {
  if (!a || !b) {
    return false
  }
  const aProps = Object.getOwnPropertyNames(a)
  const bProps = Object.getOwnPropertyNames(b)
  if (aProps.length !== bProps.length) {
    return false
  }
  for (const propertyName of aProps) {
    const propertyA = a[propertyName]
    const propertyB = b[propertyName]
    if (!b.hasOwnProperty(propertyName)) {
      return false
    }
    if (propertyA instanceof Object) {
      if (!isObjectValueEqual(propertyA, propertyB)) {
        return false
      }
    } else if (propertyA !== propertyB) {
      return false
    }
  }
  return true
}

/**
 * 数组、数组对象去重
 * @param {EmptyArrayType} arr 数组内容
 * @param {string} attribute 需要去重的键值（数组对象）
 * @returns {EmptyArrayType} 去重后的数组
 */
export function removeDuplicate(arr: EmptyArrayType, attribute?: string) {
  if (Object.keys(arr).length === 0) {
    return arr
  } else {
    if (attribute) {
      const object: EmptyObjectType = {}
      return arr.reduce((current: EmptyArrayType[], item: EmptyArrayType) => {
        const key = item[attribute as keyof typeof item]
        if (!object[key]) {
          object[key] = true
          current.push(item)
        }
        return current
      }, [])
    } else {
      return [...new Set(arr)]
    }
  }
}
